include ActionView::Helpers::DateHelper
class Usuario < ActiveRecord::Base
  #misc
  acts_as_authentic
  default_scope :order => "username"
  named_scope :activos, :order => "nombres", :conditions => ["activo = ?", 1]
  named_scope :find_all_by_area_id, lambda {  |id|  {:conditions=>["cargo_id in (?)",Area.find_by_id(id).cargo_ids]}}
  named_scope :por_area, lambda { |area|
    {:joins=>:cargo, :conditions=>{"cargos.area_id"=>area.to_s}}
  }
 
  named_scope :hi_ordenado, :order => "historicos_internos.hasta DESC"
  CIVIL = %w(Soltera/o Casada/o Divorciada/o Viuda/o)
  named_scope :vigentes, :conditions=> {:deleted_at => nil}
  #Relaciones
  
  has_and_belongs_to_many :perfiles
  has_and_belongs_to_many :predefinidos
  has_many :planes_acciones
	#has_and_belongs_to_many :planes_acciones
  has_and_belongs_to_many :hobbies
  has_and_belongs_to_many :talentos
  has_many :premiaciones
  belongs_to :sucursal
  belongs_to :cargo
  has_one :area,:through=>:cargo
  belongs_to :evaluacion
  
  has_many :autorizaciones,  :order => 'fecha'
  has_many :marcaciones,  :order => 'fecha, hora'
  has_many :solicitudes_respuestas
  has_many :cuentas
  has_many :familiares
  has_many :recibos
  has_many :movimientos
  has_many :respuestas
  has_many :evaluados
  has_many :prestamos
  has_many :formaciones
  has_many :documentos
  has_many :incidentes, :class_name => "Incidente", :foreign_key => "funcionario_id"
  has_many :idiomas, :class_name => "IdiomaUsuario", :foreign_key => :usuario_id
  
  has_many :planes_horarios
  has_many :grupos_horarios, :through => :planes_horarios
  
  has_many :historicos_internos
  has_many :historicos_externos
  
  has_many :vacaciones
  has_many :reconocimientos
  has_many :solicitudes_documentos, :class_name => "SolicitudDocumento"
  has_many :examenes
  has_many :carpetas
  has_many :logs
  
  has_many  :usuarios_preguntas
  has_many  :resultados_competencias,:order=>"competencia_nombre"
  has_many :preguntas, :through => :usuarios_preguntas
  has_many :datos,:class_name => "UsuarioDato"
  has_one :uniforme, :dependent=>:destroy
  has_attached_file :foto,
    :styles => { :original => "150x150>"}  
  #Validaciones
  #validates_length_of :num_cuenta, :maximum => 10
  validates_attachment_content_type :foto, :content_type => ['image/jpeg', 'image/png']

  COMPARACIONES={"Mayor o igual a"=>">=","Menor o igual a"=>"<="}
  #Campos para el ajaxpopup
  attr_writer :cargo_nombre
  attr_accessor :vacaciones_consideradas
  delegate :nombre, :to => :cargo, :prefix => true, :allow_nil => true
  

  def contratos_por_periodo
    periodos=[]
    nro_periodo=0
    contratos=self.historicos_internos.find(:all,:order=>"desde desc")
    contratos.each_with_index do  |contrato,i|
      periodos[nro_periodo]||={:texto=>"Periodo: ",:contratos=>[]}
      periodos[nro_periodo][:contratos]<<contrato
      if (contratos[i+1] and contratos[i+1].hasta!=contrato.desde) or !contratos[i+1]
        desde=periodos[nro_periodo][:contratos].last.desde
        hasta=periodos[nro_periodo][:contratos].first.hasta
        periodos[nro_periodo][:antiguedad]=self.calcular_antiguedad(desde,hasta)
        hasta=Date.today if hasta.blank?
        periodos[nro_periodo][:texto]+=" #{I18n.l(desde) if desde} - #{I18n.l(hasta) if hasta}"
        nro_periodo+=1
      end
    end
    periodos.each{ |p| p[:contratos].reverse!}
  end
  #TODO: Verificar la utilidad de los metodos que involucran a los modulos
  def modulos_principales
    @modulos_principales=[]
    self.perfiles.each{|p| @modulos_principales.concat(p.modulos_principales)}
    @modulos_principales.uniq!
    @modulos_principales
  end

  def area
    cargo.try(:area)
  end

  def submodulos
    @submodulos=[]
    self.perfiles.each{|p| @submodulos.concat(p.submodulos)}
    @submodulos.uniq!
    @submodulos.sort{|m1,m2| m1.orden<=>m2.orden  }
  end

  def modulo_ids
    @modulos_ids=[]
    self.perfiles.each{|p| @modulos_ids.concat(p.modulo_ids)}
    @modulos_ids.uniq!
    @modulos_ids
  end

  def actualizar_historico_laboral(parametros)
    hi_ultimo=nil
    hi_ultimo=self.historicos_internos.ultimo.first unless self.historicos_internos.empty?

    hi_nuevo=HistoricoInterno.new()
    hi_nuevo.sucursal_id=parametros[:sucursal_id]
    hi_nuevo.cargo_id=parametros[:cargo_id]

    unless hi_ultimo.blank?
      hi_ultimo.hasta=Date.today
      hi_ultimo.save
      hi_nuevo.nivel_id=hi_ultimo.nivel_id
      hi_nuevo.beneficio=hi_ultimo.beneficio
      hi_nuevo.viatico=hi_ultimo.viatico
    end

    hi_nuevo.salario=parametros[:sueldo]
    hi_nuevo.desde=Date.today
    hi_nuevo.save

    self.historicos_internos << hi_nuevo
  end


  def self.rango_edad(edad)
    case
    when  edad < 24 then rango= "Menos de 24 años"
    when (edad >= 24 and edad <= 30) then rango= "De 24 a 30 años"
    when (edad >= 30 and edad <= 35) then rango= "De 30 a 35 años"
    when  edad > 35  then  rango= "Mas de 35 años"
    end
    rango
  end

  def self.franja_antiguedad(anios)
    case
    when  anios < 1 then franja= "Menos de 1 año"
    when (anios >= 1 and anios <= 3) then franja= "De 1 a 3 años"
    when (anios >= 3 and anios <= 5) then franja= "De 3 a 5 años"
    when  anios > 5  then  franja= "Mas de 5 años"
    end
    franja
  end


  def vacaciones_disponibles(a=antiguedad)
    return 0 if a["fecha_ingreso"].nil?
    periodo_anterior=(a["años"]>1 or self.vacaciones_negociadas.to_i>0) ? dias_disponibles(a,false) : 0
    periodo_actual  = dias_disponibles(a)
    periodo_anterior+periodo_actual
  end

  def dias_disponibles(antiguedad,actual=true)
    actual ? (anios=antiguedad["años"]) : (anios=antiguedad["años"]-1)
    dias_correspondientes= (self.vacaciones_negociadas.to_i>0) ? self.vacaciones_negociadas : VacacionAntiguedad.dias_por_antiguedad(anios)
    ini=antiguedad["fecha_ingreso"].advance(:years=>anios)
    fin=antiguedad["fecha_ingreso"].advance(:years=>anios+1,:days=>-1)
    dias_usados=0
    self.vacaciones_consideradas||=[]
    self.vacaciones.en_periodo(ini,fin).each do |v|
      unless self.vacaciones_consideradas.include?(v)
        self.vacaciones_consideradas<<v
        #dias_usados+=v.dias_usados_por_usuario(self)
        dias_usados+=v.cantidad_dias
      end
    end

    resultado=(dias_correspondientes-dias_usados)
    resultado
  end



  #Checkea si el usuario tiene tal perfil
  def tiene_perfil?(nombre)
    p = Perfil.find_by_nombre(nombre)
    self.perfiles.include?(p)
  end
  
  def antiguedad
    historicos=self.historicos_internos.find(:all,:order=>"desde desc")
    desde = nil
    unless historicos.empty?
      historicos.each { |hi|
        if hi.hasta && desde
          if (desde - hi.hasta) > 0
            desde
            break
          else
            desde = hi.desde
          end
        else
          desde = hi.desde
        end
      } 
    end
    hasta=nil
    calcular_antiguedad(desde,hasta)
  end
  
  def calcular_antiguedad(fecha_ingreso,fecha_salida)
    return {"fecha_ingreso" => fecha_ingreso,"años"=>0,"meses"=>0,"dias"=>0,"texto"=>"No Tiene"} if fecha_ingreso.nil?
    fecha_salida||=Time.now
    a=distance_of_time_in_words_hash(fecha_ingreso,fecha_salida,:locale=>:"es-AR")
    ["años","meses","dias"].each{|k| a[k]||=0}
    hm=(a["años"]+a["meses"]+a["dias"])>0  ? ["minutos","horas","segundos"] : []
    t=distance_of_time_in_words(fecha_ingreso,fecha_salida,false,:locale=>:"es-AR",:except=>hm)
    {"fecha_ingreso" => fecha_ingreso,"texto"=>t}.merge(a)
  end
  
  def es_activo?
    self.activo == 0 ? "No" : "Si"
  end

  def edad
    fecha_nacimiento.nil? ? "N/A" : ((Date.today - fecha_nacimiento).to_i / 365).to_s + ' ' + "a&ntilde;os"
  end

  def nombre
    "#{self.nombres} #{self.apellidos}"
  end

  def nombre_to_filename
    nombre.downcase.gsub(' ', '_')
  end

  def borrar_predefinidos(anho, mes)
    movimientos = self.movimientos.predefinidos.periodo(Time.mktime(anho, mes,1), Time.mktime(anho, mes).at_end_of_month )
    movimientos.each {|m| m.destroy}
  end

  def generar_predefinidos(anho, mes)

    self.predefinidos.each do |mov|
      nuevo = self.movimientos.new
      case mov.tipo
      when 0 #valor fijo
        nuevo.valor = mov.valor
      when 1 #sueldo 1
        nuevo.valor = ((mov.valor / 100) * self.sueldo).round
      when 2 #sueldo 2
        nuevo.valor = ((mov.valor / 100) * self.sueldo2).round
      end
      nuevo.tipo_movimiento = mov.tipo_movimiento
      nuevo.fecha = Time.mktime(anho, mes).at_end_of_month
      nuevo.predefinido = true
      nuevo.save
    end

  end

  #EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONESEVALUACIONES
  #EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONESEVALUACIONES
  #EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONES EVALUACIONESEVALUACIONES
  
  def usuarios_para_reporte
    usuarios = []
    id_perfil_atencion_mails=Parametro.find(:first,:select=>'parametrizable_id',:conditions=>{:codigo=>'PPERF01'}).try(:parametrizable_id)
    if self.perfil_ids.include?(Perfil.find(:first,:select=>'id',:conditions=>{:id=>id_perfil_atencion_mails}).try(:id))
      usuarios.concat(Usuario.activos)
    elsif self.cargo
      usuarios = [self]
      usuarios.concat(subordinados)
    end
    usuarios
  end
  
  def evalua_a?(usuario, evaluacion)
    Evaluado.find(:first, :conditions => ['usuario_id = ? AND evaluado_id = ? AND evaluacion_id = ?', self.id,  usuario.id, evaluacion.id])
  end

  # START solo para resultados por evaluador
  #TODO: Fix no pregunta que evaluacion corresponde!!!
  def resultado_por_tipo_evaluado(evaluacion,tipo_evaluado)
    logger.info "Inicio calculo"
    logger.info "Traer competencias de cargos"
    competencias = self.cargo.competencias_all
    logger.info "Calcular evaluadores"
    evaluadores  = evaluadores(evaluacion,tipo_evaluado)
    logger.info "Crear vector"
    total        = []
    logger.info "Recorrer competencias"
    competencias.each do |competencia|
      logger.info "Competencia #{competencia.titulo}"
      total << resultado_por_competencia_por_tipo_evaluado(evaluacion,competencia, 'all', tipo_evaluado, evaluadores).to_f
    end
    resultado_total = evaluadores.size > 0 ?  total.sum / evaluadores.size :  0.0
    logger.info "Fin calculo: #{total.inspect}= #{total.sum} / #{evaluadores.size} = #{resultado_total.to_f}"
    resultado_total / 2.0
  end


  def resultado_por_competencia_por_tipo_evaluado(evaluacion,competencia, tipo, tipo_evaluado, evaluadores)
    respuestas, total_max_competencia = respuesta_y_maximo(evaluacion,competencia, tipo)
    total_evaluadores   = []
    evaluadores.each do |evaluador|
      respuestas_end    = []
      respuestas_filter = respuestas.select { |respuesta| respuesta.usuario_id == evaluador.id && respuesta.evaluado_id == self.id }
      preguntas         = respuestas_filter.map(&:pregunta_id).uniq
      preguntas.each do |p|
        respuestas_end <<  respuestas_filter.select {|r| r.pregunta_id == p}.first
      end

      total_evaluadores << respuestas_end.sum(&:valor)
    end
    total_evaluadores.sum
  end
  # END solo para resultados por evaluador

  def evaluadores(evaluacion,tipo_evaluado = nil)
    if tipo_evaluado
      if tipo_evaluado == 'par'
        evaluado = Evaluado.find(:all, :conditions => ["usuario_id <> ? AND evaluado_id = ? AND tipo = ? AND evaluacion_id = ?", self.id, self.id, tipo_evaluado,evaluacion.id ])
      elsif tipo_evaluado == 'autoevaluacion'
        evaluado = Evaluado.find(:all, :conditions => ["usuario_id = ? AND evaluado_id = ? AND evaluacion_id = ?", self.id, self.id,evaluacion.id ])
      else
        evaluado = Evaluado.find(:all, :conditions => ["evaluado_id = ? AND tipo = ? AND evaluacion_id = ?", self.id, tipo_evaluado,evaluacion.id ])
      end
    else
      evaluado = Evaluado.find(:all, :conditions => ["evaluado_id = ? AND evaluacion_id = ?", self.id,evaluacion.id ])
    end
    evaluadores = evaluado.map(&:usuario)
    evaluadores
  end

  def porcentaje_por_pregunta(pregunta)
    # estas resouestas debe ser filtradas por usuario no por preguntas como las demas
    res_filter = pregunta.respuestas.evaluado(self.id)
    respuestas    = []
    usuarios  = res_filter.map(&:usuario_id).uniq
    usuarios.each do |u|
      respuestas <<  res_filter.select {|r| r.usuario_id == u}.first
    end
    
    total      = respuestas.map(&:valor).sum
    ( respuestas.size > 0 && pregunta.maxima_opcion > 0 ) ? ( total * 100 ) / ( pregunta.maxima_opcion *  respuestas.size )  : 0.0
  end

  def porcentaje_competencias(evaluacion,tipo = 'all',tipo_evaluado = nil)

    if tipo == :especifica
      competencias = self.cargo.competencias
    elsif tipo == :general
      competencias = Competencia.find(:all, :conditions => {:tipo => 'general'})
    else
      competencias = self.cargo.competencias_all
    end

    total = []
    competencias.each do |competencia|
      total << resultado_por_competencia(evaluacion,competencia, tipo, tipo_evaluado)
    end
    total_sin_ceros = total.select {|t| t > 0}
    #porque los valores ceros son de competencias con preguntas no respondidas
    #y no habria q tenerlas en cuenta
    total_sin_ceros.size > 0 ?  total_sin_ceros.sum / total_sin_ceros.size :  0
  end

  ## Promedio general del sistema
  def resultado_por_competencia(evaluacion,competencia, tipo, tipo_evaluado = nil)

    respuestas, total_max_competencia = respuesta_y_maximo(evaluacion,competencia, tipo)
    total_evaluadores = []
    #Resultado por evaluadores
    evaluadores = evaluadores(evaluacion,tipo_evaluado)
    evaluadores.each do |evaluador|
      respuestas_end    = []
      respuestas_filter = respuestas.select { |respuesta| respuesta.usuario_id == evaluador.id && respuesta.evaluado_id == self.id }
      preguntas         = respuestas_filter.map(&:pregunta_id).uniq
      preguntas.each do |p|
        respuestas_end <<  respuestas_filter.select {|r| r.pregunta_id == p}.first
      end
      total_evaluadores << respuestas_end.sum(&:valor)
    end
    porcentaje_evaluadores    = evaluadores.size > 0 ? (total_evaluadores.sum / evaluadores.size ) : 0.0
    porcentaje_de_competencia = total_max_competencia > 0 ? (( porcentaje_evaluadores * 100 ) / total_max_competencia) : 0.0
    porcentaje_de_competencia
  end

  def respuesta_y_maximo(evaluacion,competencia, tipo = 'all')
    #Resultado por Tipo de Competencias
    preguntas=competencia.preguntas.por_evaluacion(evaluacion)
    if tipo == :general
      respuestas            = preguntas.map(&:respuestas).flatten
      total_max_competencia = preguntas.map{|p| p.maxima_opcion.to_f * self.filtrar_respuestas(p.respuestas).size}.sum
    elsif tipo == :especifica
      respuestas            = preguntas.select{|pregunta| pregunta.cargo_id == self.cargo_id }.map(&:respuestas).flatten
      total_max_competencia = preguntas.select{|pregunta| pregunta.cargo_id == self.cargo_id }.map{|p| p.maxima_opcion * self.filtrar_respuestas(p.respuestas).size}.sum
    else
      competencia_ids=self.preguntas.por_evaluacion(evaluacion).collect{|p| p.competencia_id}.uniq
      respuestas            = preguntas.select{|pregunta| pregunta.cargo_id == self.cargo_id ||
          pregunta.cargo_id == nil ||
          competencia_ids.include?(pregunta.competencia_id)
      }.map(&:respuestas).flatten
      total_max_competencia = preguntas.select{|pregunta| pregunta.cargo_id == self.cargo_id ||
          pregunta.cargo_id == nil ||
          competencia_ids.include?(pregunta.competencia_id) }.map{|p| p.maxima_opcion * self.filtrar_respuestas(p.respuestas).size}.sum
    end

    [respuestas, total_max_competencia]
  end

  def filtrar_respuestas(respuestas)
    res_filter = respuestas.evaluado(self.id)
    res_end    = []
    preguntas  = res_filter.map(&:pregunta_id).uniq
    preguntas.each do |p|
      res_end <<  res_filter.select {|r| r.pregunta_id == p}.first
    end
    res_end
  end

  ## START funcion only for reportes
  def porcentaje_competencias_por_evaluador(evaluacion,tipo, evaluador, tipo_evaluado = nil)
    if tipo == :especifica
      competencias = self.cargo.nil? ? [] : self.cargo.competencias
    else
      competencias = Competencia.find(:all, :conditions => {:tipo => 'general'})
    end
    total = []
    competencias.each do |competencia|
      total << resultado_por_evaluador(evaluacion,competencia, tipo, evaluador)
    end
    total.size > 0 ?  total.sum / total.size :  0
  end

  def resultado_competencias_por_evaluador(evaluacion,tipo, evaluador)
    preguntas=self.usuarios_preguntas.por_evaluacion(evaluacion).select{|up| up.pregunta.competencia_tipo==tipo.to_s}.map(&:pregunta)
    sum_respuestas=0
    sum_max=0
    preguntas.each do |p|
      if p.respuestas.evaluado(self.id).evaluador(evaluador.id).first
        respuesta=p.respuestas.evaluado(self.id).evaluador(evaluador.id).first
        sum_respuestas+=respuesta.valor
        sum_max+=p.maxima_opcion
      end
    end
    sum_max > 0 ? (sum_respuestas/sum_max)*100 : 0.0
  end

  def resultado_por_evaluador(evaluacion,competencia, tipo, evaluador)
    respuestas, total_max_competencia = respuesta_y_maximo(evaluacion,competencia, tipo)
    respuestas_filter = respuestas.select { |respuesta| respuesta.usuario_id == evaluador.id && respuesta.evaluado_id == self.id }
    respuestas_end    = []
    preguntas         = respuestas_filter.map(&:pregunta_id).uniq
    preguntas.each do |p|
      respuestas_end <<  respuestas_filter.select {|r| r.pregunta_id == p}.first
    end

    total_evaluado = respuestas_end.sum(&:valor)
    total_max_competencia > 0 ? (( total_evaluado * 100 ) / total_max_competencia) : 0.0
  end

  ## END

  #  def respuestas(evaluacion, competencia = nil)
  #    if competencia
  #      evaluacion.preguntas.por_competencia(competencia.id).map{|p| p.respuestas.evaluado(self.id)}.flatten.compact
  #    else
  #      evaluacion.preguntas.competencias_cargo(self.cargo_id).map{|p| p.respuestas.evaluado(self.id) }.flatten.compact
  #    end
  #  end

  def en_relacion_con(usuario_evaluado_id, evaluacion_id)
    unless self.id == usuario_evaluado_id
      evaluado = self.evaluados.find(:first, :conditions => ['evaluado_id = ? AND evaluacion_id = ?', usuario_evaluado_id, evaluacion_id])
      evaluado.tipo if evaluado
    else
      "autoevaluacion"
    end
  end

  def comentarios(pregunta)
    comentarios = []
    respuestas = pregunta.respuestas.evaluado(self.id)
    respuestas.select { |respuesta| comentarios << [respuesta.comentario, respuesta.opcion_elegida ] unless respuesta.comentario.blank? }
    comentarios
  end



  def seleccionar_usuarios(evaluacion)
    if evaluados.por_evaluacion(evaluacion.id).empty? && cargo
      crear_evaluacion_para(seleccionar_superior,     'superior',    evaluacion)
      crear_evaluacion_para(seleccionar_pares,        'par',         evaluacion)
      crear_evaluacion_para(seleccionar_subordinados, 'subordinado', evaluacion)
    else
      unless evaluados.por_evaluacion.include?(self)
        crear_evaluacion_para([self], 'par', evaluacion)
      end
    end
  end

  def crear_evaluacion_para(usuarios, tipo, evaluacion)
    unless usuarios.blank?
      usuarios.each do |usuario|
        evaluado=Evaluado.create(:usuario_id    => self.id,
          :evaluado_id   => usuario.id,
          :evaluacion_id => evaluacion.id,
          :tipo          => tipo,
          :estado        => 'incompleta')
        evaluado.evaluado.asignar_preguntas(evaluacion)
        evaluado.evaluado.asignar_datos(evaluacion)
        evaluado.usuario.asignar_datos(evaluacion)
        evaluado.save
      end
    end
  end
  
 
  def superiores
    usuarios = []
    if cargo
      # filter   = !!cargo.area
      usuarios = cargo.cargos_superiores.map {|cargo| cargo.usuarios.activos }.flatten
    end
    usuarios
  end

  def subordinados
    usuarios = []
    if cargo
      # filter = !!cargo.area
      usuarios = cargo.cargos_subordinados.map {|cargo| cargo.usuarios.activos }.flatten
    end
    usuarios
  end

  def pares
    usuarios = []
    if cargo
      # filter = !!cargo.area
      usuarios = cargo.cargos_pares.map {|cargo| cargo.usuarios.activos }.flatten
    end
    usuarios
  end

  def asignar_preguntas(evaluacion, fixit=false)
    #logger.info "FIXIT:  #{fixit}"
    #logger.info "EVALUACION:  #{evaluacion}"

    preguntas_asignadas=self.preguntas.por_evaluacion(evaluacion)
    #logger.info "\nPREGUNTASaSIGNADAS #{preguntas_asignadas.count}"
    return unless (fixit or preguntas_asignadas.empty?)
    logger.info "\nPASO PASO PASO"
    changed=false
    #Preguntas a asignar por ser de competencias relacionadas al cargo
    preguntas   = evaluacion.preguntas.competencias_cargo(self.cargo_id).reject{|p| preguntas_asignadas.include?(p)}
    preguntas.each do |p|
      UsuarioPregunta.create(:usuario=>self,:pregunta=>p)#join preguntas filter pregunta.evaluacion
    end
    preguntas_asignadas.concat(preguntas)
    #Preguntas por estar relacionadas de forma directa al cargo
    preguntas_por_cargo=evaluacion.preguntas.find_all_by_cargo_id(self.cargo_id)
    preguntas   = preguntas_por_cargo.reject{|p| preguntas_asignadas.include?(p)}
    preguntas.each do |p|
      UsuarioPregunta.create(:usuario=>self,:pregunta=>p)#join preguntas filter pregunta.evaluacion
      changed=true
    end

    competencias_asignadas = self.resultados_competencias.por_evaluacion(evaluacion).map(&:competencia).uniq
    #logger.info "\n\n\ncompetencias_asignadas #{competencias_asignadas.inspect}"

    competencias   = self.preguntas.por_evaluacion(evaluacion).map(&:competencia).uniq
    #logger.info "\n\n\ncompetencias #{competencias.inspect}"

    competencias   = competencias.reject{|c| competencias_asignadas.include?(c)}
    #logger.info "\n\n\ncompetencias #{competencias.count}"

    competencias.each do |competencia|
      #logger.info "competencia: #{competencia.inspect}"
      rc=ResultadoCompetencia.new
      rc.usuario=self
      rc.evaluacion=evaluacion
      rc.competencia=competencia
      rc.competencia_nombre=competencia.titulo
      rc.jefes=self.resultado_por_competencia(evaluacion,competencia, "all", "subordinado")
      rc.pares=self.resultado_por_competencia(evaluacion,competencia, "all", "par")
      rc.subordinados=self.resultado_por_competencia(evaluacion,competencia, "all", "superior")
      rc.autoevaluacion=self.resultado_por_competencia(evaluacion,competencia, "all", "autoevaluacion")
      rc.promedio=self.resultado_por_competencia(evaluacion,competencia, "all",nil)
      rc.save
    end
    if changed
      Evaluado.find_all_by_evaluado_id_and_evaluacion_id(self.id,evaluacion.id).each do |eva|
        eva.estado="incompleta"
        eva.save
      end
    end
  end

  def asignar_datos(evaluacion)
    return unless UsuarioDato.por_usuario_y_evaluacion(self,evaluacion).empty?
    if self.cargo.nil?
      cargo="~Cargo eliminado"
      area="~No se pudo determinar"
    else
      cargo=self.cargo.nombre
      area=self.cargo.area.nombre
    end

    if self.sucursal.nil?
      filial="~Filial eliminada"
    else
      filial=self.sucursal.nombre
    end
    UsuarioDato.create(:usuario=>self,
      :filial=>filial,
      :area=>area,
      :cargo=>cargo,
      :evaluacion=>evaluacion)
  end

  def asignar_resultado_por_competencia(evaluacion)
    return if evaluacion.terminada
    resultados_por_competencias=self.resultados_competencias.por_evaluacion(evaluacion)
    if !resultados_por_competencias.empty?
      puts "ACTUALIZANDO resultado_por_competencia"
      actualizar_resultados_por_competencia(resultados_por_competencias)
      return
    end
    puts "CREANDO resultado_por_competencia"
    competencias   = self.preguntas.por_evaluacion(evaluacion).map(&:competencia).uniq
    competencias.each do |competencia|
      rc=ResultadoCompetencia.new
      rc.usuario=self
      rc.evaluacion=evaluacion
      rc.competencia=competencia
      rc.competencia_nombre=competencia.titulo
      rc.jefes=self.resultado_por_competencia(evaluacion,competencia, "all", "subordinado")
      rc.pares=self.resultado_por_competencia(evaluacion,competencia, "all", "par")
      rc.subordinados=self.resultado_por_competencia(evaluacion,competencia, "all", "superior")
      rc.autoevaluacion=self.resultado_por_competencia(evaluacion,competencia, "all", "autoevaluacion")
      rc.promedio=self.resultado_por_competencia(evaluacion,competencia, "all",nil)
      rc.save
    end
  end

  def actualizar_resultados_por_competencia(resultados_por_competencias)
    resultados_por_competencias.each do |rc|
      rc.jefes=self.resultado_por_competencia(rc.evaluacion,rc.competencia, "all", "subordinado")
      rc.pares=self.resultado_por_competencia(rc.evaluacion,rc.competencia, "all", "par")
      rc.subordinados=self.resultado_por_competencia(rc.evaluacion,rc.competencia, "all", "superior")
      rc.autoevaluacion=self.resultado_por_competencia(rc.evaluacion,rc.competencia, "all", "autoevaluacion")
      rc.promedio=self.resultado_por_competencia(rc.evaluacion,rc.competencia, "all",nil)
      rc.save
    end
  end

  def resultado_tipo_competencia(tipo,evaluacion)
    preguntas=self.usuarios_preguntas.por_evaluacion(evaluacion)

    case tipo
    when :especificas
      especificas=preguntas.select{|p| (p.pregunta.competencia_tipo.match('especifica'))}
      suma=0
      cantidad=especificas.count
      especificas.each{ |e| suma+=(e.resultado ? e.resultado : 0.0)}
      porcentaje =  cantidad > 0 ? (suma/(100*cantidad))*100 : 0
    when  :generales
      generales=preguntas.select{|p| (p.pregunta.competencia_tipo.match('general'))}
      suma=0
      cantidad=generales.count
      generales.each{ |g| suma+=(g.resultado ? g.resultado : 0.0)}
      porcentaje = cantidad > 0 ?  (suma/(100*cantidad))*100 : 0
    end
    porcentaje
  end

  def self.planilla_funcionarios(mes,anio)
    csv_string = FasterCSV.generate(:encoding=>'U') do |csv|
      # header row
      csv << ["Mes","Año","Filial","Nro. Funcionario", "Funcionario","Fecha de Ingreso",

        "Antiguedad","Franja Antiguedad", "Area", "Cargo","Horas diarias de Trabajo",

        "Fecha Nacimiento","Edad","Rango Edad","Categoria","Hijos Femeninos","Hijos Masculinos",

        "IPS Empresa","IPS Personal","Tipo de Contrato","Cantidad de Horas a ser Pagadas",

        "Cantidad Ausencias","Regencia","Comision Visitadores","Comision Vendedor","Valor cobrado por horas extras",

        "Valor descontado por ausencias","Franja Salarial","Sueldo base en Guaranies",

        "Sueldo bruto con beneficios y comisiones","IVA","Patronal","Bonificacion","PRAEP",

        "Estado Civil","Padres Solteros","Sexo","Dias de Vacaciones en el mes","Nacionalidad",

        "Grupo Sanguineo","Ciudad de residencia"
      ]
      # data rows
      self.activos.all.each do |user|
        hijas=user.familiares.hijas.count
        hijos=user.familiares.hijos.count
        antiguedad=user.antiguedad
        area=user.cargo.try(:area).try(:nombre)
        cargo=user.cargo.try(:nombre)
        edad=user.edad.to_i
        recibo=user.recibos.por_mes_y_anio(mes,anio).aguinaldos?(false).first
        sueldo_base=user.sueldo
        sueldo2=user.sueldo2 #sueldo minimo
        sueldo_bruto_byc=recibo.try(:sueldo_bruto_beneficios)
        sueldo_minimo=Parametro.find_by_codigo('PV00').valor.to_f
        if recibo
          movimientos=recibo.try(:movimientos)
          bonificacionFamiliar = movimientos.bonificaciones.sum :valor
          iva=movimientos.ivas.sum :valor
          praep=movimientos.praeps.sum :valor
          regencia = movimientos.regencias.sum :valor
          comision_visitador=movimientos.comisiones.sum :valor
          valor_horas_extras=movimientos.horas_extras.sum :valor
          valor_ausencias=recibo.ausencias
        end
        tipo_contrato=user.historicos_internos.last.try(:tipo_contrato).try(:nombre)

        patronal=0
        ips_empresa=0
        ips_personal=0
        tipos_movimiento=[]
        user.predefinidos.each{|p| tipos_movimiento<<p.tipo_movimiento_id}

        if tipos_movimiento.include?(APP_CONFIG[:ips25].to_i)
          ips_personal=0.255*sueldo_minimo
        elsif tipos_movimiento.include?(APP_CONFIG[:ips9].to_i)
          patronal=0.165*sueldo_minimo
          ips_empresa=0.09*sueldo_minimo
        end

        csv << [
          mes,
          anio,
          user.sucursal.try(:nombre), #filial
          user.codigo, #Nro. Funcionario
          user.nombre, #Funcionario
          antiguedad["fecha_ingreso"], # Fecha de Ingreso
          antiguedad["texto"], #Antiguedad
          Usuario.franja_antiguedad(antiguedad["años"]),#"Franja Antiguedad"
          area,
          cargo,
          "",#"Horas diarias de Trabajo"
          user.fecha_nacimiento,
          edad,
          Usuario.rango_edad(edad), #Rango Edad
          "",#"Categoria"
          hijas, #Hijos Femeninos
          hijos, #Hijos Masculinos
          ips_empresa,
          ips_personal,
          tipo_contrato,
          "",#"Cantidad de Horas a ser Pagadas"
          "",#"Cantidad Ausencias"
          regencia,#"Regencia"
          comision_visitador,#"Comision Visitadores"
          "",#"Comision Vendedor"
          valor_horas_extras,#"Valor cobrado por horas extras"
          valor_ausencias,#"Valor descontado por ausencias"
          "",#Franja salarial
          sueldo_base,#"Sueldo base en Guaranies"
          sueldo_bruto_byc.to_i,#sueldo bruto con beneficios y comisiones
          iva,#"IVA"
          patronal,#"Patronal"
          bonificacionFamiliar,#"Bonificacion"
          praep,#"PRAEP"
          user.civil, #Estado Civil
          ((user.civil=="Soltero" or user.civil=="Divorciado") and (hijos+hijas>0)) ? "si":"no", #Padres Solteros
          user.sexo,#"Sexo"
          "",#"Dias de Vacaciones en el mes"
          user.nacionalidad,
          user.tipo_sangre,#Grupo Sanguineo
          user.ciudad#Ciudad de Residencia
        ]
      end
    end
  end

  protected

  def seleccionar_superior
    tam = superiores.size
    rtn = tam > 0 ? [superiores[rand(tam)]] : []
    rtn
  end

  def seleccionar_pares
    rtn = pares.reject{|par| par == self}.sort_by{rand}.slice(0, 2)
    rtn << self
    rtn
  end

  def seleccionar_subordinados
    subordinados.sort_by{rand}.slice(0, 2)
  end

end

